import json
import os
import binascii
import subprocess
import time
from datetime import datetime

import Global
import sys

def convert_file_to_hex(file_path):
    """
    读取文件并转换为十六进制字符串
    :param file_path: 文件路径
    :return: 十六进制字符串
    """
    try:
        with open(file_path, 'rb') as f:
            content = f.read()
            hex_data = binascii.hexlify(content).decode('utf-8')
            return hex_data
    except Exception as e:
        print(f"读取文件失败: {str(e)}")
        return None

# def write_hex_to_qrc(hex_data, output_path):
#     """
#     将十六进制数据写入qrc.py文件，以字节字符串格式保存
#     :param hex_data: 十六进制字符串
#     :param output_path: 输出文件路径
#     """
#     try:
#         # 将十六进制字符串按每16个字节分组
#         hex_lines = [hex_data[i:i+32] for i in range(0, len(hex_data), 32)]
#
#         # 构建格式化的字节字符串
#         formatted_data = 'DllData = b"'
#         for i, line in enumerate(hex_lines):
#             # 将每两个字符转换为\x格式
#             formatted_line = ''.join('\\x' + line[i:i+2] for i in range(0, len(line), 2))
#             # 添加行尾的反斜杠，最后一行除外
#             if i < len(hex_lines) - 1:
#                 formatted_data += formatted_line + '\\\\n'
#             else:
#                 formatted_data += formatted_line + '"'
#
#         with open(output_path, 'w') as f:
#             f.write(formatted_data)
#         print(f"成功写入文件: {output_path}")
#     except Exception as e:
#         print(f"写入文件失败: {str(e)}")
def write_hex_to_qrc(hex_data, output_path):
    """
    将十六进制数据写入qrc.py文件，以字节字符串格式保存
    :param hex_data: 十六进制字符串
    :param output_path: 输出文件路径
    """
    try:
        # 确保十六进制字符串长度为偶数
        if len(hex_data) % 2 != 0:
            raise ValueError("十六进制字符串长度必须为偶数")

        # 直接按每两个字符转换为\x格式
        formatted_data = 'DllData = b"'
        formatted_data += ''.join(f'\\x{hex_data[i:i+2]}' for i in range(0, len(hex_data), 2))
        formatted_data += '"'

        with open(output_path, 'w') as f:
            f.write(formatted_data)
        print(f"成功写入文件: {output_path}")
    except Exception as e:
        print(f"写入文件失败: {str(e)}")


def update_version(build_count=None):
    """
    更新版本号，格式为YYYYMMDD.XX，其中XX为编译次数
    :param build_count: 可选，手动指定编译次数
    :return: 更新后的版本号
    """
    config_file = 'build_config.json'
    current_date = datetime.now().strftime('%Y%m%d')
    
    try:
        with open(config_file, 'r') as f:
            config = json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        config = {'last_build_date': '', 'build_count': 0}
    
    # 如果日期变更或手动指定编译次数，重置或更新计数器
    if build_count is not None:
        config['build_count'] = build_count
    elif config['last_build_date'] != current_date:
        config['build_count'] = 1
    else:
        config['build_count'] += 1
    
    config['last_build_date'] = current_date
    version = f"{current_date}.{config['build_count']:02d}"
    
    # 更新配置文件
    with open(config_file, 'w') as f:
        json.dump(config, f, indent=4)
    
    # 更新Global.py中的VERSION变量
    with open('Global.py', 'r', encoding='utf-8') as f:
        content = f.read()
    
    new_content = content.replace(f'G_VER = "{Global.G_VER}"', f'G_VER = "{version}"')
    with open('Global.py', 'w', encoding='utf-8') as f:
        f.write(new_content)
    
    return version

def clean_pycache():
    """清理所有__pycache__目录"""
    for root, dirs, _ in os.walk('.'):
        for dir_name in dirs:
            if dir_name == '__pycache__':
                cache_dir = os.path.join(root, dir_name)
                try:
                    for file in os.listdir(cache_dir):
                        file_path = os.path.join(cache_dir, file)
                        os.remove(file_path)
                    os.rmdir(cache_dir)
                    print(f'已清理: {cache_dir}')
                except Exception as e:
                    print(f'清理{cache_dir}时出错: {str(e)}')


def Nuitkabuild_executable():
    """
    使用Nuitka打包main.py
    """
    try:
        # 更新版本号
        version = update_version()
        
        # 创建临时工作目录
        temp_dir = 'temp_build'
        if os.path.exists(temp_dir):
            import shutil
            #shutil.rmtree(temp_dir)
        
        # 复制并处理项目文件
        #copy_project_files('.', temp_dir)
        
        # 切换到临时目录执行打包
        python_path = sys.executable
        cmd = [python_path, '-m', 'nuitka',
               '--standalone',
               '--onefile',
               '--remove-output',
               '--windows-icon-from-ico=./UI/dog.ico',
               '--include-data-files=./UI/dog.ico=UI/dog.ico',#相对使用图标路径
               #'--include-data-files=venv/Lib/site-packages/ddddocr/*.onnx=ddddocr/',
               '--include-data-dir=./Res=Res',

               '--nofollow-import-to=图色',
               '--nofollow-import-to=模拟器',
               '--nofollow-import-to=注入',
               '--windows-console-mode=disable',
               '--follow-imports',
               #'--lto=yes',
               '--enable-plugin=pyqt6',
               #'--plugin-enable=numpy',
               #'--include-qt-plugins=platforms',
               '--jobs=40',
               f'--output-filename=七骑士{version}.exe',
               #'--output-dir=../dist',
               #f'{temp_dir}/main.py']
               '--output-dir=dist',
                'AppMain.py']

        
        # 在临时目录中执行打包命令
        #result = subprocess.run(cmd, check=True, cwd=temp_dir)
        result = subprocess.run(cmd, check=True,encoding='utf-8')
        if result.stderr:
            print("错误输出:", result.stderr)
            
        # 清理临时目录
        import shutil
        #shutil.rmtree(temp_dir)
        
        # 清理__pycache__目录
        clean_pycache()
        
        print("打包完成！")
    except subprocess.CalledProcessError as e:
        print(f"打包失败，返回码: {e.returncode}")
        print(f"错误输出: {e.stderr}")
        print(f"标准输出: {e.stdout}")
    except FileNotFoundError as e:
        print(f"找不到文件或命令: {e.filename}")
    except Exception as e:
        print(f"发生错误: {str(e)}")
    finally:
        # 确保临时目录被清理
        if os.path.exists('temp_build'):
            import shutil
            #shutil.rmtree('temp_build')
def process_file(input_path, output_path):
    """
    处理文件：读取、转换、写入
    :param input_path: 输入文件路径
    :param output_path: 输出文件路径
    """
     # 删除目标文件（如果存在）
    if os.path.exists(output_path):
        os.remove(output_path)
        print(f"已删除文件: {output_path}")
    hex_data = convert_file_to_hex(input_path)
    if hex_data:
        write_hex_to_qrc(hex_data, output_path)
        # 文件处理完成后进行打包

if __name__ == '__main__':
    # 示例使用
    print("当前工作目录:", os.getcwd())
    # input_file = 'G:\\工作区\\尤米尔传奇\\Ymir\\x64\\Release\\Ymir.dll'  # 替换为实际的输入文件路径
    # output_file = os.path.join('UI', 'qrc.py')  # 输出到UI目录下的qrc.py
    # process_file(input_file, output_file)
    clean_pycache()

    start_time = time.time()
    Nuitkabuild_executable()
    end_time = time.time()  # 记录结束时间
    elapsed_time = end_time - start_time
    minutes = int(elapsed_time // 60)  # 计算分钟
    seconds = int(elapsed_time % 60)  # 计算剩余秒数

    print(f"Nuitka编译耗时: {minutes}分{seconds}秒")
    #nuitka编译命令
    #nuitka --standalone --onefile  --remove-output --windows-console-mode=disable --windows-icon-from-ico=./UI/ymir.ico --include-data-files=./UI/ymir.ico=UI/ymir.ico --lto=yes --output-dir=dist --output-filename=尤米尔插件.exe --enable-plugin=pyqt6 main.py


